package com.qingcheng.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.qingcheng.dao.BrandMapper;
import com.qingcheng.dao.SpecMapper;
import com.qingcheng.service.goods.SkuSearchService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Welcome to the most Amazing IntelliJ IIIDEA.
 * Creat0r: ^_^ fffantianxing ^_^
 * Date: 2019-07-08
 * Time: 12:07
 */
@Service
public class SkuSearchServiceImpl implements SkuSearchService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Autowired
    private BrandMapper brandMapper;
    @Autowired
    private SpecMapper specMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public Map skuSearch(Map<String, String> searchMap) throws IOException {

        //封装请求对象
        SearchRequest searchRequest = new SearchRequest("sku");
        searchRequest.types("doc");//设置查询的类型
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();


        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//布尔查询构建器

        //关键字搜索
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", searchMap.get("keywords"));
        boolQueryBuilder.must(matchQueryBuilder);

        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);

        //商品分类过滤查询
        if (searchMap.get("category") != null) {
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("categoryName", searchMap.get("category"));
            boolQueryBuilder.filter(termQueryBuilder);
        }

        //商品品牌分类过滤
        if (searchMap.get("brandName") != null) {
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("brandName", searchMap.get("brandName"));
            boolQueryBuilder.filter(termQueryBuilder);
        }

        //商品spec查询
        for (String key : searchMap.keySet()) {
            if (key.startsWith("spec.")) {
//                searchMap.get(key).replace("\t", "+");
                System.out.println(searchMap.get(key));
                TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(key + ".keyword", searchMap.get(key));
                boolQueryBuilder.filter(termQueryBuilder);
            }
        }

        //商品价格查询
        if (searchMap.get("price") != null) {
            String[] prices = searchMap.get("price").split("-");
            if (!"0".equals(prices[0])) {
                RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").gte(prices[0] + "00");
                boolQueryBuilder.filter(rangeQueryBuilder);
            }
            if (!"*".equals(prices[1])) {
                RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").lte(prices[1] + "00");
                boolQueryBuilder.filter(rangeQueryBuilder);
            }
        }

        //聚合查询（商品分类）
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("sku_category").field("categoryName");
        searchSourceBuilder.aggregation(termsAggregationBuilder);

        int currentPage = Integer.parseInt(searchMap.get("currentPage"));//获取用户提交的当前页码
        int pageSize = 30;//设置每页显示数量为30条

        currentPage = (currentPage - 1) * pageSize;//设置查询开始页

        searchSourceBuilder.from(currentPage);//设置开始页
        searchSourceBuilder.size(pageSize);//设置每页显示数量

        //设置排序规则
        String sort = searchMap.get("sort");
        String sortOrder = searchMap.get("sortOrder");
        System.out.println(sort);
        System.out.println(sortOrder);
        if (!"".equals(sort)){
            searchSourceBuilder.sort(sort, SortOrder.valueOf(sortOrder));
        }

        //设置高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name").preTags("<font color=red>").postTags("</font>");
        searchSourceBuilder.highlighter(highlightBuilder);

        //获取响应结果
        Map resultMap = new HashMap();
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        //商品列表
        SearchHits searchHits = searchResponse.getHits();
        long totalHits = searchHits.getTotalHits();
        System.out.println("记录数：" + totalHits);
        SearchHit[] hits = searchHits.getHits();
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (SearchHit hit : hits) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();

            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField nameHighlight = highlightFields.get("name");
            Text[] fragments = nameHighlight.fragments();
            Text fragment = fragments[0];
            sourceAsMap.put("name",fragment.toString());

            resultList.add(sourceAsMap);
        }
        Long totalCount = searchHits.getTotalHits();
        Long totalPage = totalCount%pageSize==0?(totalCount/pageSize):(totalCount/pageSize+1);//计算总页数
        System.out.println(totalPage);
        resultMap.put("totalPage", totalPage);
        resultMap.put("rows", resultList);

        //2.2 商品分类列表
        Terms terms = searchResponse.getAggregations().get("sku_category");

        List<? extends Terms.Bucket> buckets = terms.getBuckets();
        List<String> categoryList = new ArrayList();
        for (Terms.Bucket bucket : buckets) {
            categoryList.add(bucket.getKeyAsString());
        }
        resultMap.put("categoryList", categoryList);

        //商品品牌名称
        String categoryName = "";
        if (searchMap.get("category") == null) {
            if (categoryList.size() > 0) {
                categoryName = categoryList.get(0);
            }
        } else {
            categoryName = searchMap.get("category");
        }

        List<Map> brand = null;
        brand = (List<Map>) redisTemplate.boundHashOps("brand").get(categoryName);//从缓存中查询brand
        resultMap.put("brand", brand);

        //商品spec
        List<Map> specList = null;
        specList = (List<Map>) redisTemplate.boundHashOps("spec").get(categoryName);//从缓存中查询spec
        for (Map specMap : specList) {
            String[] options = ((String) specMap.get("options")).split(",");
            System.out.println(specMap.get("options"));
            specMap.put("options", options);
        }
        resultMap.put("specList", specList);


        return resultMap;
    }
}
